package com.changgou.goods.service.impl;

import com.alibaba.fastjson.JSON;
import com.changgou.goods.dao.*;
import com.changgou.goods.pojo.*;
import com.changgou.goods.service.SpuService;
import com.changgou.util.IdWorker;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.netflix.discovery.converters.Auto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class SpuServiceImpl implements SpuService {

    @Autowired
    private SpuMapper spuMapper;

    @Autowired
    private SkuMapper skuMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private BrandMapper brandMapper;

    @Autowired
    private CategoryBrandMapper categoryBrandMapper;

    @Autowired
    private IdWorker idWorker;

    /**
     * 查询全部列表
     * @return
     */
    @Override
    public List<Spu> findAll() {
        return spuMapper.selectAll();
    }

    /**
     * 根据ID查询
     * @param id
     * @return
     */
    @Override
    public Spu findById(String id){
        return  spuMapper.selectByPrimaryKey(id);
    }


    /**
     * 增加
     * @param goods
     */
    @Transactional
    @Override
    public void add(Goods goods){
        //1、获取spu
        Spu spu = goods.getSpu();

        //2、给spu封装一些参数，一共加4个字段的数据，还要加1个skuList
        //2.1、设置spuId
        long id = idWorker.nextId();
        spu.setId(String.valueOf(id));
        //2.2、设置删除状态
        spu.setIsDelete("0");
        //2.3、设置上架状态
        spu.setIsMarketable("0");
        //2.4、设置审核状态
        spu.setStatus("0");

        //3、添加到spu表中
        spuMapper.insert(spu);

        //4、添加sku
        this.saveSkuList(goods);
    }

    //添加sku的方法，
    private void saveSkuList(Goods goods) {
        //1、获取skuList
        List<Sku> skuList = goods.getSkuList();

        //2、遍历skuList，将每一条sku信息都添加到sku表中，一共加9个字段的数据
        if (skuList!=null){//这是对一个集合进行判空
            for (Sku sku : skuList) {
                //一、设置skuId
                long id = idWorker.nextId();
                sku.setId(String.valueOf(id));

                //二、设置规格，没传值，也要设置为{}
                if (StringUtils.isEmpty(sku.getSpec())){//这是对一个字符串进行判空
                    sku.setSpec("{}");
                }

                //三、设置sku名称name（spu名称+sku规格数据）
                //------------获取spu名称
                Spu spu = goods.getSpu();
                String name = spu.getName();
                //将sku规格从json数据，转为map，因为前台传过来的就是json格式的
                Map<String,String> map = JSON.parseObject(sku.getSpec(), Map.class);
                //遍历map，将每一个key（规格名称）对应的value（具体的规格参数），和name拼接起来
                for (String value : map.values()) {
                    name+=" "+value;//这里在""漏掉了空格，这是在调试中发现的
                }
                //设置sku的名称
                sku.setName(name);

                //四、设置sku中对应的spuId，------------从spu中获取其spuId
                sku.setSpuId(spu.getId());

                //五、设置创建时间
                sku.setCreateTime(new Date());

                //六、设置修改时间
                sku.setUpdateTime(new Date());

                //七、设置商品分类id，------------从spu中获取的
                Category category = categoryMapper.selectByPrimaryKey(spu.getCategory3Id());
                //Integer categoryId = category.getId();
                Integer category3Id = spu.getCategory3Id();
                sku.setCategoryId(category3Id);

                //八、设置商品分类名称
                sku.setCategoryName(category.getName());

                //九、设置品牌名称，------------同样，从spu中，根据其id，获取brand对象
                Integer brandId = spu.getBrandId();
                Brand brand = brandMapper.selectByPrimaryKey(spu.getBrandId());
                sku.setBrandName(brand.getName());

                //十、补充：要做的是，将品牌和分类关联起来
                //首先要封装一个CategoryBrand对象，然后设置其中的categoryId和brandId，然后去到数据库中查询，
                //看看是否能查询出来，若不能，则将该CategoryBrand对象添加到表中
                CategoryBrand categoryBrand=new CategoryBrand(category3Id,brandId);
                int count = categoryBrandMapper.selectCount(categoryBrand);
                if (count==0){
                    //即没查出来关联信息
                    categoryBrandMapper.insert(categoryBrand);
                }

                //十、将每一条sku，添加到sku表中
                skuMapper.insert(sku);
            }
        }

    }



    /**
     * 修改
     * @param spu
     */
    @Override
    @Transactional
    public void update(Spu spu){
        spuMapper.updateByPrimaryKey(spu);
    }

    //修改goods
    @Override
    @Transactional
    public void update2(Goods goods) {
        //1、修改spu
        Spu spu = goods.getSpu();
        int i = spuMapper.updateByPrimaryKey(spu);
        ///因为客户端传过来的spu中并没有指定id，而上面的代码又需要根据id修改呢，当然不会修改成功。。。
        // 所以，想要测试 修改功能，就写个死数据id，并封装到spu中  （如下所示）

       /* String spuId="1367773496863621120";//在数据库中，找到brand_id=12的spu所对应的id
        spu.setId(spuId);
        int i = spuMapper.updateByPrimaryKey(spu);*/

        //2、修改sku
        //2.1、删除原有的sku
        Example example=new Example(Sku.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("spuId",spu.getId());
        skuMapper.deleteByExample(example);
        //2.2、新增sku（调用之前写好的新增sku的方法）
        this.saveSkuList(goods);
    }

    /**
     * 删除
     * @param id
     */
    @Override
    public void delete(String id){
        spuMapper.deleteByPrimaryKey(id);
    }


    /**
     * 条件查询
     * @param searchMap
     * @return
     */
    @Override
    public List<Spu> findList(Map<String, Object> searchMap){
        Example example = createExample(searchMap);
        return spuMapper.selectByExample(example);
    }

    /**
     * 分页查询
     * @param page
     * @param size
     * @return
     */
    @Override
    public Page<Spu> findPage(int page, int size){
        PageHelper.startPage(page,size);
        return (Page<Spu>)spuMapper.selectAll();
    }

    /**
     * 条件+分页查询
     * @param searchMap 查询条件
     * @param page 页码
     * @param size 页大小
     * @return 分页结果
     */
    @Override
    public Page<Spu> findPage(Map<String,Object> searchMap, int page, int size){
        PageHelper.startPage(page,size);
        Example example = createExample(searchMap);
        return (Page<Spu>)spuMapper.selectByExample(example);
    }

    //根据spuId，查询Goods对象
	@Override
	public Goods findBySpuId(String spuId) {
    	//1、查询出来spu
		Spu spu1 = spuMapper.selectByPrimaryKey(spuId);

		//2、查询sku
		Example example=new Example(Sku.class);
		Example.Criteria criteria = example.createCriteria();
		criteria.andEqualTo("spuId",spuId);
		List<Sku> skus = skuMapper.selectByExample(example);

		//3、将查询来的spu、sku，都封装到goods对象中
		Goods goods=new Goods();
		goods.setSpu(spu1);
		goods.setSkuList(skus);

		return goods;
	}

	//修改新增的商品的审核状态、上下架状态
    @Override
    @Transactional
    public void audit(String spuId) {
        //1、取出spu
        Spu spu = spuMapper.selectByPrimaryKey(spuId);

        //2、判断是否取出spu
        if (spu==null){
            throw new RuntimeException("商品不存在");
        }

        //3、判断spu是否为已删除状态
        if ("1".equals(spu.getIsDelete())){
            throw new RuntimeException("商品处于删除状态");
        }

        //4、修改spu审核状态
        spu.setStatus("1");

        //5、修改spu上下架状态
        spu.setIsMarketable("1");

        //6、添加到数据库中
        int i = spuMapper.updateByPrimaryKeySelective(spu);
        System.out.println(i);
    }


    @Override
    @Transactional
    //修改 要删除的商品 的下架为 已下架（即，只有已下架状态，才可以删除）
    //下架商品
    public void pull(String spuId) {
        Spu spu = spuMapper.selectByPrimaryKey(spuId);

        if (spu==null){
            //没查出来spu
            throw new RuntimeException("没有该商品");
        }

        //设置spu的上下架状态为 已上架
        spu.setIsMarketable("0");

        //添加到tb_spu表中
        int i = spuMapper.updateByPrimaryKeySelective(spu);
        System.out.println(i);
    }

    //修改 要上架的商品的审核状态和上下架状态
    //即，上架新增商品
    @Override
    @Transactional
    public void put(String spuId) {
        Spu spu = spuMapper.selectByPrimaryKey(spuId);
        if (spu==null){
            //没查出来spu
            throw new RuntimeException("没有该商品");
        }

        //判断商品的审核状态
        String status = spu.getStatus();
        if ("0".equals(status)){
            //未审核的商品不能上架
            throw new RuntimeException("不能上架该商品");
        }

        //通过前面2步的筛查,修改上下架状态，并更新到tb_spu中
        spu.setIsMarketable("1");
        spuMapper.updateByPrimaryKeySelective(spu);
    }

    //逻辑删除商品
    @Override
    @Transactional
    public void delete2(String spuId) {
        //1、获取spu，并判空
        Spu spu = spuMapper.selectByPrimaryKey(spuId);
        if (spu==null){
            throw new RuntimeException("没有查询到该商品");
        }

        //2、判断审核状态
        if ("0".equals(spu.getStatus())){
            throw new RuntimeException("该商品正在审核中...");
        }

        //3、修改删除状态
        spu.setIsDelete("1");
        spuMapper.updateByPrimaryKeySelective(spu);
    }

    @Override
    @Transactional
    public void restore(String spuId) {
        //1、获取spu，并判空
        Spu spu = spuMapper.selectByPrimaryKey(spuId);
        if (spu==null){
            throw new RuntimeException("没有查询到该商品");
        }

        //2、判断是否处于删除状态
        if ("0".equals(spu.getIsDelete())){
            throw new RuntimeException("该商品还未删除...");
        }

        //3、修改spu表
        spu.setIsDelete("0");
        spuMapper.updateByPrimaryKeySelective(spu);
    }

    //物理删除商品
    @Override
    @Transactional
    public void realDelete(String spuId) {
        //1、获取spu，并判空
        Spu spu = spuMapper.selectByPrimaryKey(spuId);
        if (spu==null){
            throw new RuntimeException("没有查询到该商品");
        }

        //2、判断是否处于删除状态
        if ("0".equals(spu.getIsDelete())){
            //未删除，返异常
            throw new RuntimeException("该商品还没处于删除状态");
        }

        //3、执行删除操作
        spuMapper.deleteByPrimaryKey(spu);
    }

    /**
     * 构建查询对象
     * @param searchMap
     * @return
     */
    private Example createExample(Map<String, Object> searchMap){
        Example example=new Example(Spu.class);
        Example.Criteria criteria = example.createCriteria();
        if(searchMap!=null){
            // 主键
            if(searchMap.get("id")!=null && !"".equals(searchMap.get("id"))){
                criteria.andEqualTo("id",searchMap.get("id"));
           	}
            // 货号
            if(searchMap.get("sn")!=null && !"".equals(searchMap.get("sn"))){
                criteria.andEqualTo("sn",searchMap.get("sn"));
           	}
            // SPU名
            if(searchMap.get("name")!=null && !"".equals(searchMap.get("name"))){
                criteria.andLike("name","%"+searchMap.get("name")+"%");
           	}
            // 副标题
            if(searchMap.get("caption")!=null && !"".equals(searchMap.get("caption"))){
                criteria.andLike("caption","%"+searchMap.get("caption")+"%");
           	}
            // 图片
            if(searchMap.get("image")!=null && !"".equals(searchMap.get("image"))){
                criteria.andLike("image","%"+searchMap.get("image")+"%");
           	}
            // 图片列表
            if(searchMap.get("images")!=null && !"".equals(searchMap.get("images"))){
                criteria.andLike("images","%"+searchMap.get("images")+"%");
           	}
            // 售后服务
            if(searchMap.get("saleService")!=null && !"".equals(searchMap.get("saleService"))){
                criteria.andLike("saleService","%"+searchMap.get("saleService")+"%");
           	}
            // 介绍
            if(searchMap.get("introduction")!=null && !"".equals(searchMap.get("introduction"))){
                criteria.andLike("introduction","%"+searchMap.get("introduction")+"%");
           	}
            // 规格列表
            if(searchMap.get("specItems")!=null && !"".equals(searchMap.get("specItems"))){
                criteria.andLike("specItems","%"+searchMap.get("specItems")+"%");
           	}
            // 参数列表
            if(searchMap.get("paraItems")!=null && !"".equals(searchMap.get("paraItems"))){
                criteria.andLike("paraItems","%"+searchMap.get("paraItems")+"%");
           	}
            // 是否上架
            if(searchMap.get("isMarketable")!=null && !"".equals(searchMap.get("isMarketable"))){
                criteria.andEqualTo("isMarketable",searchMap.get("isMarketable"));
           	}
            // 是否启用规格
            if(searchMap.get("isEnableSpec")!=null && !"".equals(searchMap.get("isEnableSpec"))){
                criteria.andEqualTo("isEnableSpec", searchMap.get("isEnableSpec"));
           	}
            // 是否删除
            if(searchMap.get("isDelete")!=null && !"".equals(searchMap.get("isDelete"))){
                criteria.andEqualTo("isDelete",searchMap.get("isDelete"));
           	}
            // 审核状态
            if(searchMap.get("status")!=null && !"".equals(searchMap.get("status"))){
                criteria.andEqualTo("status",searchMap.get("status"));
           	}

            // 品牌ID
            if(searchMap.get("brandId")!=null ){
                criteria.andEqualTo("brandId",searchMap.get("brandId"));
            }
            // 一级分类
            if(searchMap.get("category1Id")!=null ){
                criteria.andEqualTo("category1Id",searchMap.get("category1Id"));
            }
            // 二级分类
            if(searchMap.get("category2Id")!=null ){
                criteria.andEqualTo("category2Id",searchMap.get("category2Id"));
            }
            // 三级分类
            if(searchMap.get("category3Id")!=null ){
                criteria.andEqualTo("category3Id",searchMap.get("category3Id"));
            }
            // 模板ID
            if(searchMap.get("templateId")!=null ){
                criteria.andEqualTo("templateId",searchMap.get("templateId"));
            }
            // 运费模板id
            if(searchMap.get("freightId")!=null ){
                criteria.andEqualTo("freightId",searchMap.get("freightId"));
            }
            // 销量
            if(searchMap.get("saleNum")!=null ){
                criteria.andEqualTo("saleNum",searchMap.get("saleNum"));
            }
            // 评论数
            if(searchMap.get("commentNum")!=null ){
                criteria.andEqualTo("commentNum",searchMap.get("commentNum"));
            }

        }
        return example;
    }

}
